/*
 * Copyright 2012 NJUT  qixiaobo. All rights reserved.
 */
package com.fujitsu.nanjing.tieba.service;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.fujitsu.nanjing.tieba.base.BaseService;
import com.fujitsu.nanjing.tieba.constrant.CommonParamter;
import com.fujitsu.nanjing.tieba.ibator.CoreAttach;
import com.fujitsu.nanjing.tieba.ibator.CoreBoard;
import com.fujitsu.nanjing.tieba.ibator.CoreCreditsLog;
import com.fujitsu.nanjing.tieba.ibator.CoreReply;
import com.fujitsu.nanjing.tieba.ibator.CoreReportLog;
import com.fujitsu.nanjing.tieba.ibator.CoreShortMsg;
import com.fujitsu.nanjing.tieba.ibator.CoreTopic;
import com.fujitsu.nanjing.tieba.ibator.CoreTopicCriteria;
import com.fujitsu.nanjing.tieba.ibator.CoreTopicCriteria.Criteria;
import com.fujitsu.nanjing.tieba.ibator.CoreTrashBox;
import com.fujitsu.nanjing.tieba.model.Topic;
import com.fujitsu.nanjing.tieba.struct.FileStruct;

/**
 * TopicService.java
 * 
 * @author Qixiaobo-win8
 */

@Service
@Transactional
public class TopicService extends BaseService<CoreTopic, CoreTopicCriteria> {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(TopicService.class);

	@Resource
	private Topic topic;
	@Resource
	private BoardService boardService;
	@Resource
	private AttachService attachService;
	@Resource
	private UserService userService;
	@Resource
	private TrashBoxService trashBoxService;
	@Resource
	private ReplyService replyService;
	@Resource
	private ShortMessageService shortMessageService;
	@Resource
	private ReportLogService reportLogService;
	@Resource
	private CreditsLogService creditsLogService;
	@Override
	public CoreTopic findById(String id) {
		return topic.selectByPrimaryKey(Integer.parseInt(id));
	}

	@Override
	public CoreTopic insert(CoreTopic t) {
		initTopic(t);
		int id = topic.insertSelective(t);
		t.setTopicid(id);
		userService.updateUserPosts(t.getUserid());
		return t;
	}

	@Override
	public void update(CoreTopic t) {
		topic.updateByPrimaryKeySelective(t);

	}

	@Override
	public void delete(CoreTopic t) {
		recycle(t);
		t.setState(CommonParamter.删除帖子);
		update(t);
		List<CoreReply> replies = replyService.findRepliesByTopicId(t
				.getTopicid());
		for (CoreReply reply : replies) {
			replyService.delete(reply);
		}
		// topic.deleteByPrimaryKey(t.getBoardid());

	}
	private void recycle(CoreTopic t) {
		CoreTrashBox trashBox = new CoreTrashBox();
		trashBox.setTopicid(t.getTopicid());
		trashBox.setReplyid(0);
		trashBox.setCreatetime(new Date());
		trashBox.setTopictitle(t.getTitle());
		CoreBoard board = boardService.findById(t.getBoardid().toString());
		trashBox.setBoardname(board.getBoardname());
		trashBox.setBoardid(t.getBoardid());
		trashBox.setDeleteuser(getUserDetails().getUsername());
		trashBox.setUserid(t.getUserid());
		trashBoxService.insert(trashBox);
		List<CoreReply> replies = replyService.findRepliesByTopicId(t
				.getTopicid());
		for (CoreReply reply : replies) {
			replyService.recycle(reply);
		}

	}

	/** 根据boardid查找数据 */
	public List<CoreTopic> findAllByBoardId(int boardid, int offset,
			int length, String order) {
		CoreTopicCriteria example = new CoreTopicCriteria();
		example.setMysqlLength(length);
		example.setMysqlOffset(offset);
		example.setOrderByClause(order);
		example.createCriteria().andBoardidEqualTo(boardid)
				.andStateNotEqualTo(CommonParamter.删除帖子);
		return topic.selectByExampleWithBLOBs(example);
	}

	/** 根据boardid查找数据,默认分页长度为10 */
	public List<CoreTopic> findAllByBoardIdDefault(int boardid, int offset) {
		// CoreTopicCriteria example = new CoreTopicCriteria();
		// example.setMysqlLength(CommonParamter.默认分页长度);
		// if (offset > 0) {
		// example.setMysqlOffset((offset - 1) * CommonParamter.默认分页长度);
		// }
		// example.setOrderByClause(CommonParamter.默认主题排序条件);
		// example.createCriteria().andBoardidEqualTo(boardid)
		// .andStateNotEqualTo(CommonParamter.删除帖子);
		// return topic.selectByExampleWithBLOBs(example);
		int begin = (offset - 1) * CommonParamter.默认分页长度;
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("begin", begin);
		map.put("boardid", boardid);
		return topic.selectTopicsByBoardIdAndPageBegin(map);
	}
	public int countByBoardId(int boardId) {
		// CoreTopicCriteria example = new CoreTopicCriteria();
		// example.createCriteria().andBoardidEqualTo(boardId)
		// .andStateNotEqualTo(CommonParamter.删除帖子);
		// return topic.countByExample(example);
		return topic.countTopicsPages(boardId);
	}

	public int count() {
		return topic.countTopics();
	}
	/**
	 * @return topicid
	 * */
	public int insertWithAttaches(CoreTopic t, List<FileStruct> fileStructs) {
		t = insert(t);
		for (FileStruct fileStruct : fileStructs) {
			insertAttach(fileStruct, t);
		}
		return t.getTopicid();

	}
	private void insertAttach(FileStruct fileStruct, CoreTopic t) {

		CoreAttach coreAttach = new CoreAttach();
		MultipartFile file = fileStruct.getFile();
		if (file.getContentType().startsWith("image")) {

			logger.info("上传图片：" + file.getOriginalFilename());
		} else {
			logger.info("上传文件：" + file.getOriginalFilename());
		}
		coreAttach.setFilename(file.getOriginalFilename());
		coreAttach.setTitle(fileStruct.getTitle());
		coreAttach.setUserid(t.getUserid());
		coreAttach.setCredits(fileStruct.getCredits());
		coreAttach.setFilesize((int) file.getSize());
		// 产生随机的名字
		String tempName = String.valueOf(System.nanoTime())
				+ file.getOriginalFilename().substring(
						file.getOriginalFilename().lastIndexOf("."));
		coreAttach.setLocalname(tempName);
		coreAttach.setTopicid(t.getTopicid());
		coreAttach.setLocalid((short) fileStruct.getLocalid());
		// 将文件写入upload目录下
		File dest = new File(CommonParamter.webRoot + CommonParamter.uploadPath
				+ File.separatorChar + tempName);
		try {
			file.transferTo(dest);
		} catch (IllegalStateException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		attachService.insert(coreAttach);
	}
	public void initTopic(CoreTopic t) {
		Date date = new Date();
		t.setLastposttime(date);
		t.setCreatetime(date);
		t.setReplies(0);
		// 每次发帖，奖励一分
		t.setReward(CommonParamter.默认悬赏);
		t.setVisits(0);
		CoreBoard board = boardService.findById(t.getBoardid().toString());
		t.setSectionid(board.getSectionid());
		t.setUpdatetime(date);
	}
	/**
	 * 板块展示最后发表的主题
	 **/
	public CoreTopic findLastTopicByBoardid(int boardId) {
		return topic.getLastTopicByBoardId(boardId);
	}
	/** 根据date查找数据,默认分页长度为10 */
	public List<CoreTopic> findNewTopics(Date date, int offset) {
		CoreTopicCriteria example = new CoreTopicCriteria();
		example.setMysqlLength(CommonParamter.默认分页长度);
		if (offset > 0) {
			example.setMysqlOffset((offset - 1) * CommonParamter.默认分页长度);
		}
		example.setOrderByClause(CommonParamter.默认主题排序条件);
		example.createCriteria().andCreatetimeGreaterThan(date)
				.andStateNotEqualTo(CommonParamter.删除帖子);
		return topic.selectByExampleWithBLOBs(example);
	}
	/**
	 * 根据时间获取数目
	 * */
	public int countByDate(Date date) {
		CoreTopicCriteria example = new CoreTopicCriteria();
		example.createCriteria().andCreatetimeGreaterThan(date)
				.andStateNotEqualTo(CommonParamter.删除帖子);
		return topic.countByExample(example);
	}

	/** 根据date查找数据,默认分页长度为10 */
	public List<CoreTopic> findTopicsByBoardIdAndType(int type, int boardId,
			int offset) {
		CoreTopicCriteria example = new CoreTopicCriteria();
		example.setMysqlLength(CommonParamter.默认分页长度);
		if (offset > 0) {
			example.setMysqlOffset((offset - 1) * CommonParamter.默认分页长度);
		}
		example.setOrderByClause(CommonParamter.默认主题排序条件);
		Criteria criteria = example.createCriteria().andBoardidEqualTo(boardId);
		switch (type) {
			case CommonParamter.精华 :
				criteria.andIsdigestEqualTo(CommonParamter.YES);
				break;
			case CommonParamter.悬赏 :
				criteria.andRewardGreaterThan(CommonParamter.默认悬赏);
				break;
			default :
				break;
		}
		criteria.andStateNotEqualTo(CommonParamter.删除帖子);
		return topic.selectByExampleWithBLOBs(example);
	}

	/**
	 * 根据类型获取数目
	 * */
	public int countByBoardId(int type, int boardId) {
		CoreTopicCriteria example = new CoreTopicCriteria();
		Criteria criteria = example.createCriteria().andBoardidEqualTo(boardId);
		switch (type) {
			case CommonParamter.精华 :
				criteria.andIsdigestEqualTo(CommonParamter.YES);
				break;
			case CommonParamter.悬赏 :
				criteria.andRewardGreaterThan(CommonParamter.默认悬赏);
				break;
			default :
				break;
		}
		return topic.countByExample(example);
	}
	/**
	 * 根据时间获取总页数
	 * */
	public int findPageCountByDate(Date lastAccess) {
		int pageCount = (int) Math.ceil((double) countByDate(lastAccess)
				/ CommonParamter.默认分页长度);
		if (pageCount == 0) {
			pageCount = 1;
		}
		return pageCount;
	}
	/**
	 * 当用户访问一次增加访问量时调用
	 * */
	public void addVisits(String topicId) {
		CoreTopic coreTopic = findById(topicId);
		coreTopic.setVisits(coreTopic.getVisits() + 1);
		update(coreTopic);
	}
	/**
	 * 当用户发表新回复时调用
	 * */
	public void addReplies(String topicId) {
		CoreTopic coreTopic = findById(topicId);
		coreTopic.setReplies(coreTopic.getReplies() + 1);
		update(coreTopic);
	}

	public List<CoreTopic> findTopicByUserId(String userId, int offset) {
		CoreTopicCriteria example = new CoreTopicCriteria();
		example.setMysqlLength(CommonParamter.默认分页长度);
		if (offset > 0) {
			example.setMysqlOffset((offset - 1) * CommonParamter.默认分页长度);
		}
		example.setOrderByClause(CommonParamter.默认主题排序条件);
		example.createCriteria().andUseridEqualTo(userId)
				.andStateNotEqualTo(CommonParamter.删除帖子);
		return topic.selectByExampleWithBLOBs(example);
	}

	public int countByUserId(String userId) {
		CoreTopicCriteria example = new CoreTopicCriteria();
		example.createCriteria().andUseridEqualTo(userId)
				.andStateNotEqualTo(CommonParamter.删除帖子);
		return topic.countByExample(example);
	}
	/**
	 * 根据用户获取主题总页数
	 * */
	public int findPageCountByUserId(String userId) {
		int pageCount = (int) Math.ceil((double) countByUserId(userId)
				/ CommonParamter.默认分页长度);
		if (pageCount == 0) {
			pageCount = 1;
		}
		return pageCount;
	}
	/**
	 * 获取今天发布主题数
	 * */
	public int countNewTopicsByBoardId(int boardId) {
		return topic.countTopicByBoardId(boardId);
	}
	/**
	 * 根据friendId获取<code>friend</code>总页数
	 * */
	public int findPageCount(String topicId) {
		CoreTopic coreTopic = findById(topicId);
		if (coreTopic == null) {
			return 0;
		}
		int pageCount = (int) Math.ceil((double) coreTopic.getReplies()
				/ CommonParamter.默认分页长度);
		if (pageCount == 0) {
			pageCount = 1;
		}
		return pageCount;
	}
	/**
	 * 当删除回复时调用，扣除回帖量
	 * */
	public void deleteReply(String topicId) {
		CoreTopic coreTopic = findById(topicId);
		coreTopic.setReplies(coreTopic.getReplies() - 1);
		update(coreTopic);
	}
	public int countDigists() {
		return topic.countDigests();
	}

	public List<CoreTopic> findTopRepliesTopics() {

		CoreTopicCriteria example = new CoreTopicCriteria();
		example.setMysqlLength(CommonParamter.默认分页长度);
		example.setOrderByClause("replies desc");
		example.createCriteria().andBoardidIsNotNull();
		return topic.selectByExampleWithoutBLOBs(example);
	}
	public List<CoreTopic> findTopVisitsTopics() {

		CoreTopicCriteria example = new CoreTopicCriteria();
		example.setMysqlLength(CommonParamter.默认分页长度);
		example.setOrderByClause("visits desc");
		example.createCriteria().andBoardidIsNotNull();
		return topic.selectByExampleWithoutBLOBs(example);
	}
	/**
	 * 删除主题 级联删除reply
	 * 
	 * @param flag
	 *            是否发送sms标记
	 * */
	public void deleteTopics(String[] topicIds, boolean flag, String reason) {
		Date now = new Date();
		String username = getUserDetails().getUsername();
		for (String topicId : topicIds) {
			CoreTopic coreTopic = findById(topicId);
			if (coreTopic != null) {

				if (flag == true) {
					sendSms(now, username, coreTopic, reason, "删除");
				}
				delete(coreTopic);
			}
		}
	}
	private void sendSms(Date now, String username, CoreTopic coreTopic,
			String reason, String type) {
		CoreShortMsg msg = new CoreShortMsg();
		msg.setCreatetime(now);
		msg.setFromuser(username);
		msg.setUserid(coreTopic.getUserid());
		msg.setTitle("主题被" + type + "！");
		StringBuilder sb = new StringBuilder();
		sb.append("主题<bold>");
		sb.append(coreTopic.getTitle());
		sb.append("</bold>被" + type + "了！<br/>原因是：<font color='red' ><bold>");
		sb.append(reason);
		sb.append("</bold></font>");
		msg.setMessage(sb.toString());
		shortMessageService.insert(msg);
	}

	public void moveTopics(String[] topicids, String moveto, boolean sendFlag,
			String reason) {
		Date now = new Date();
		String username = getUserDetails().getUsername();
		CoreBoard board = boardService.findById(moveto);
		if (board == null) {
			return;
		}
		for (String topicId : topicids) {
			CoreTopic coreTopic = findById(topicId);
			if (coreTopic != null) {

				if (sendFlag == true) {
					sendSms(now, username, coreTopic, reason,
							"移动到板块" + board.getBoardname());
				}
				move(coreTopic, board);
			}
		}

	}

	private void move(CoreTopic coreTopic, CoreBoard board) {
		coreTopic.setBoardid(board.getBoardid());
		coreTopic.setSectionid(board.getSectionid());
		update(coreTopic);

	}

	public void highLight(String[] topicids, String lightcolor,
			boolean sendFlag, String reason, Date expiredate) {
		Date now = new Date();
		String username = getUserDetails().getUsername();
		for (String topicId : topicids) {
			CoreTopic coreTopic = findById(topicId);
			if (coreTopic != null) {
				if (sendFlag == true) {
					sendSms(now, username, coreTopic, reason, "高亮" + lightcolor);
				}
				highLight(coreTopic, lightcolor, expiredate);
			}
		}

	}

	private void highLight(CoreTopic coreTopic, String lightcolor,
			Date expiredate) {
		coreTopic.setHighcolor(lightcolor);
		coreTopic.setHighexpiredate(expiredate);
		update(coreTopic);

	}

	public void close(String[] topicids, String state, boolean sendFlag,
			String reason) {
		boolean flag = false;
		if (state.equals("close")) {
			flag = true;
		}
		Date now = new Date();
		String username = getUserDetails().getUsername();
		for (String topicId : topicids) {
			CoreTopic coreTopic = findById(topicId);
			if (coreTopic != null) {

				if (sendFlag == true && isChangedSolveState(coreTopic, flag)) {
					sendSms(now, username, coreTopic, reason, flag
							? "关闭"
							: "打开");
				}
				closeTopics(coreTopic, flag);
			}
		}

	}

	private void closeTopics(CoreTopic coreTopic, boolean flag) {
		if (isChangedSolveState(coreTopic, flag)) {
			changeSolveState(coreTopic);
			update(coreTopic);
		}

	}
	private void changeSolveState(CoreTopic coreTopic) {
		if (coreTopic.getIssolved().equalsIgnoreCase("T")) {
			coreTopic.setIssolved("F");
		} else {
			coreTopic.setIssolved("T");
		}

	}

	private boolean isChangedSolveState(CoreTopic coreTopic, boolean flag) {
		return !coreTopic.getIssolved().equals(flag ? "T" : "F");
	}

	public void topScope(String[] topicids, String topScope, boolean sendFlag,
			String reason, Date expiredate) {
		Date now = new Date();
		String username = getUserDetails().getUsername();
		for (String topicId : topicids) {
			CoreTopic coreTopic = findById(topicId);
			if (coreTopic != null) {
				if (sendFlag == true) {
					sendSms(now, username, coreTopic, reason,
							getTopScope(topScope));
				}
				topScopeTopics(coreTopic, topScope, expiredate);
			}
		}

	}

	private void topScopeTopics(CoreTopic coreTopic, String topScope,
			Date expiredate) {
		coreTopic.setTopscope(topScope);
		coreTopic.setTopexpiredate(expiredate);
		update(coreTopic);

	}

	private String getTopScope(String topScope) {
		if (topScope.equals("1"))
			return "全局置顶";
		else if (topScope.equals("2")) {
			return "分区置顶";
		} else if (topScope.equals("3")) {
			return "本版置顶";
		}
		return "解除置顶";
	}

	public void digest(String[] topicids, String isDigest, boolean sendFlag,
			String reason) {
		Date now = new Date();
		String username = getUserDetails().getUsername();
		String type = isDigest.equals("T") ? "加入精华" : "解除精华";
		for (String topicId : topicids) {
			CoreTopic coreTopic = findById(topicId);
			if (coreTopic != null) {
				if (sendFlag == true) {
					sendSms(now, username, coreTopic, reason, type);
				}
				digestTopics(coreTopic, isDigest);
			}
		}

	}

	private void digestTopics(CoreTopic coreTopic, String isDigest) {
		coreTopic.setIsdigest(isDigest);
		update(coreTopic);

	}

	public void updateWithAttaches(CoreTopic topic, List<FileStruct> fileStructs) {
		update(topic);
		attachService.deleteByTopicId(topic.getTopicid());
		for (FileStruct fileStruct : fileStructs) {
			insertAttach(fileStruct, topic);
		}

	}

	public void report(String[] topicids, boolean sendFlag, String reason) {
		Date now = new Date();
		String username = getUserDetails().getUsername();
		for (String topicId : topicids) {
			CoreTopic coreTopic = findById(topicId);
			if (coreTopic != null) {
				if (sendFlag == true) {
					sendSms(now, username, coreTopic, reason, "举报");
				}
				reportTopic(coreTopic, now, reason, username);
			}
		}

	}
	public void report(String topicid, boolean sendFlag, String reason) {
		Date now = new Date();
		String username = getUserDetails().getUsername();

		CoreTopic coreTopic = findById(topicid);
		if (coreTopic != null) {
			if (sendFlag == true) {
				sendSms(now, username, coreTopic, reason, "举报");
			}
			reportTopic(coreTopic, now, reason, username);
		}

	}

	private void reportTopic(CoreTopic coreTopic, Date now, String reason,
			String username) {
		CoreReportLog t = new CoreReportLog();
		t.setBoardid(coreTopic.getBoardid());
		t.setBoardname(boardService.findById(coreTopic.getBoardid().toString())
				.getBoardname());
		t.setCreatetime(now);
		t.setTopicid(coreTopic.getTopicid());
		t.setReason(reason);
		t.setReplyid(0);
		t.setReporteduser(coreTopic.getUserid());
		t.setTopictitle(coreTopic.getTitle());
		t.setUserid(username);
		reportLogService.insert(t);

	}
	public int sumOfVisits() {
		return topic.sumOfVisits();
	}
	public int countMonthNewTopics() {
		return topic.countMonthNewTopics();
	}

	public List<CoreTopic> findTopicsHighLightOrTopScope(int begin) {
		return topic.highColorOrTopScope(begin);
	}

	public List<CoreTopic> searchTopicAndReplies(HashMap<String, Object> map) {
		return topic.searchTopicAndReplies(map);
	}
	public List<CoreTopic> searchTopic(HashMap<String, Object> map) {
		return topic.searchTopic(map);
	}
	public int searchTopicAndRepliesCount(HashMap<String, Object> map) {
		return topic.searchTopicAndRepliesCount(map);
	}
	public int searchTopicCount(HashMap<String, Object> map) {
		return topic.searchTopicCount(map);
	}
	public int findPageCountSearchTopics(HashMap<String, Object> map) {
		int pageCount = (int) Math.ceil((double) searchTopicCount(map)
				/ CommonParamter.默认分页长度);
		if (pageCount == 0) {
			pageCount = 1;
		}
		return pageCount;
	}
	public int findPageCountSearchTopicsAndReplies(HashMap<String, Object> map) {
		int pageCount = (int) Math
				.ceil((double) searchTopicAndRepliesCount(map)
						/ CommonParamter.默认分页长度);
		if (pageCount == 0) {
			pageCount = 1;
		}
		return pageCount;
	}

	public void best(String chkTopicID, boolean sendFlag, String reason,
			String replyId, String isBest) {
		boolean bestFlag = isBest.equals("T");
		Date now = new Date();
		String username = getUserDetails().getUsername();

		CoreTopic coreTopic = findById(chkTopicID);
		if (coreTopic != null) {
			if (sendFlag == true) {
				sendSms(now, username, coreTopic, reason, bestFlag
						? "设为最佳回复"
						: "取消最佳回复");
			}
			bestTopic(coreTopic, replyId, isBest);
		}
	}

	private void bestTopic(CoreTopic coreTopic, String replyId, String isBest) {
		List<CoreReply> replies = replyService.findBest4Topic(coreTopic
				.getTopicid());
		for (CoreReply reply : replies) {
			reply.setIsbest("F");
			replyService.update(reply);
		}
		CoreReply reply = replyService.findById(replyId);
		if (reply != null) {
			if (!reply.getIsbest().equals(isBest)) {
				reply.setIsbest(isBest);
				if (isBest.equals("T")) {
					CoreCreditsLog credits = new CoreCreditsLog();
					credits.setAction("设为最佳回复");
					credits.setCreatetime(new Date());
					credits.setCredits(CommonParamter.最佳回复);
					credits.setFromuser(getUserDetails().getUsername());
					credits.setUserid(reply.getUserid());
					creditsLogService.insert(credits);
				}
				replyService.update(reply);
			}
		}

	}

}
